package com.example.vueblog.filter;

import com.example.vueblog.common.utils.ServletUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.ThreadContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;

/**
 * Log4j2日志追踪:可实现查看某个用户请求日志一条龙查找
 *
 * @author yushunshun
 * @date 2022/7/13 0:30
 */
@Slf4j
@WebFilter(filterName = "Log4j2Filter", urlPatterns = "/*", initParams = {@WebInitParam(name = "DESCRIPTION", value = "这是Log4j2Filter过滤器")})
@Order(1)
public class Log4j2Filter implements Filter {

    private String description;
    public static final String TRACE_ID = "traceId";
    public static final String URI = "uri";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        description = filterConfig.getInitParameter("DESCRIPTION");
        System.out.println("Log4j2日志追踪过滤器初始化:" + description);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//        log.info("==============>进入Log4j2Filter<==================");
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        // 生成一个随机数给到前端
        String traceId = UUID.randomUUID().toString().replace("-", "");
        // 随机数放到此线程的上下文中，可以在每条日志前加入。具体看下面log4j2.xml
        ThreadContext.put(TRACE_ID, traceId);
        //放入请求uri
        ThreadContext.put(URI, req.getRequestURI());
        // 随机数放到Header中，在Response Headers中可查看到此数据
        resp.addHeader(TRACE_ID, traceId);
        chain.doFilter(req, resp);
        ThreadContext.clearAll();
    }

    @Override
    public void destroy() {
        System.out.println("Log4j2日志追踪过滤器，被销毁：" + description);
    }
}
